
#ifndef SINEANALYZER_DIFF_wPWR_F_H
#define SINEANALYZER_DIFF_wPWR_F_H

#include "MY_INC/TI_SOLAR/SOLAR_F.h" // 包含太阳能相关模块头文件

// 功率分析器文件
//*********** 结构体定义 ***********//
typedef struct
{
    // 输入参数
    float SampleFreq; // 输入：信号采样频率（Hz）
    float Threshold;  // 输入：零点检测阈值（绝对值低于此值视为负半周）

    // 输出参数
    float   Vrms;    // 输出：电压有效值（RMS）
    float   Vavg;    // 输出：电压平均值（半周期绝对值平均）
    float   Vema;    // 输出：电压指数移动平均值（EMA）
    float   SigFreq; // 输出：信号频率（Hz）
    float   Irms;    // 输出：电流有效值（RMS）
    float   Prms;    // 输出：功率有效值（平均功率）
    uint8_t ZCD : 1; // 输出：零点交叉检测标志（1表示检测到）

    // 内部状态变量
    float    sum_Vacc_avg;      // 内部：电压平均值的累加器（单周期）
    float    sum_Vacc_rms;      // 内部：电压平方的累加器（用于RMS计算）
    float    sum_Vacc_ema;      // 内部：电压EMA的累加器
    float    sum_Iacc_rms;      // 内部：电流平方的累加器（用于RMS计算）
    float    sum_Pacc_rms;      // 内部：瞬时功率的累加器（电压×电流）
    float    curr_vin_norm;     // 内部：当前电压归一化值（处理负半周）
    float    curr_iin_norm;     // 内部：当前电流归一化值（处理负半周）
    uint8_t  prev_sign : 1;     // 内部：前一次采样的符号（0负/1正）
    uint8_t  curr_sign : 1;     // 内部：当前采样的符号（0负/1正）
    uint32_t nsamples;          // 内部：当前周期内的采样数
    uint32_t nsamplesMin;       // 内部：周期采样数下限（防噪声干扰）
    uint32_t nsamplesMax;       // 内部：周期采样数上限（防异常信号）
    uint8_t  slew_power_update; // 内部：功率更新计数器（每100周期更新）
    float    sum_Pacc_mul;      // 内部：多周期功率累加器（用于Prms平滑）
} SINEANALYZER_DIFF_wPWR_F;

//*********** 函数声明 ***********//
static inline void SINEANALYZER_DIFF_wPWR_F_init(SINEANALYZER_DIFF_wPWR_F *v, float SampleFreq, float Threshold,
                                                 uint32_t nsamplesMin,
                                                 uint32_t nsamplesMax) // 初始化结构体（带采样数限制）
{
    // 输入参数

    v->SampleFreq = SampleFreq;   // 输入：信号采样频率（Hz）
    v->nsamplesMin = nsamplesMin; // 内部：周期采样数下限（防噪声干扰）
    v->nsamplesMax = nsamplesMax; // 内部：周期采样数上限（防异常信号）
    v->Threshold = Threshold;     // 输入：零点检测阈值（绝对值低于此值视为负半周）
    // 输出参数
    v->Vrms = 0.0f;    // 输出：电压有效值（RMS）
    v->Vavg = 0.0f;    // 输出：电压平均值（半周期绝对值平均）
    v->Vema = 0.0f;    // 输出：电压指数移动平均值（EMA）
    v->SigFreq = 0.0f; // 输出：信号频率（Hz）
    v->Irms = 0.0f;    // 输出：电流有效值（RMS）
    v->Prms = 0.0f;    // 输出：功率有效值（平均功率）
    v->ZCD = 0;        // 输出：零点交叉检测标志（1表示检测到）

    // 内部中间状态变量
    v->sum_Vacc_avg = 0.0f;  // 内部：电压平均值的累加器（单周期）
    v->sum_Vacc_rms = 0.0f;  // 内部：电压平方的累加器（用于RMS计算）
    v->sum_Vacc_ema = 0.0f;  // 内部：电压EMA的累加器
    v->sum_Iacc_rms = 0.0f;  // 内部：电流平方的累加器（用于RMS计算）
    v->sum_Pacc_rms = 0.0f;  // 内部：瞬时功率的累加器（电压×电流）
    v->curr_vin_norm = 0.0f; // 内部：当前电压归一化值（处理负半周）
    v->curr_iin_norm = 0.0f; // 内部：当前电流归一化值（处理负半周）
    v->prev_sign = 0;        // 内部：前一次采样的符号（0负/1正）
    v->curr_sign = 0;        // 内部：当前采样的符号（0负/1正）
    v->nsamples = 0;         // 内部：当前周期内的采样数

    v->slew_power_update = 0; // 内部：功率更新计数器（每100周期更新）
    v->sum_Pacc_mul = 0.0f;   // 内部：多周期功率累加器（用于Prms平滑）
}

//*********** 内联函数实现 ***********//
static inline void SINEANALYZER_DIFF_wPWR_F_FUNC(SINEANALYZER_DIFF_wPWR_F *v, float Vin, float Iin) // 核心算法函数
{

    // 1. 信号预处理：根据阈值判断正/负半周
    v->curr_vin_norm = fabsf(Vin);             // 电压取绝对值（等效整流）
    v->curr_iin_norm = fabsf(Iin);             // 电流取绝对值
    v->curr_sign = (Bool)(Vin > v->Threshold); // 标记当前符号为正

    // 2. 零点交叉检测（ZCD）
    if ((v->prev_sign != v->curr_sign) && (v->curr_sign == 1))
    {
        // 检测到从负到正的过零（新周期开始）
        v->ZCD = 1;    // 触发零点交叉标志
        v->nsamples++; // 这里也要进行采样数递增，避免漏掉一个周期，否则会导致数据不准
        // 3. 计算周期参数
        float inv_nsamples = (1.0f) / (v->nsamples); // 计算1/nsamples（快速倒数）
        // 4. 检查周期长度是否有效（实质上控制了周期长度范围以及噪声）
        if ((v->nsamplesMin < v->nsamples) && (v->nsamples < v->nsamplesMax))
        {
            // 有效周期，计算输出值
            v->Vavg = (v->sum_Vacc_avg * inv_nsamples);      // 电压平均值
            v->Vrms = sqrtf(v->sum_Vacc_rms * inv_nsamples); // 电压RMS
            v->Vema = v->sum_Vacc_ema;                       // 电压EMA（需确认EMA逻辑）
            v->Irms = sqrtf(v->sum_Iacc_rms * inv_nsamples); // 电流RMS

            // 5. 功率计算（每100周期更新一次）
            if (++v->slew_power_update > 100)
            { // 达到100周期后更新功率
                v->slew_power_update = 0;
                v->Prms = v->sum_Pacc_mul * 0.01f; // 平均功率（100周期平均）
                v->sum_Pacc_mul = 0;               // 重置多周期累加器
            }
            else
            {
                v->sum_Pacc_mul += v->sum_Pacc_rms * inv_nsamples; // 累加单周期平均功率
            }
        }
        else
        {
            // 无效周期（噪声或异常），输出清零
            v->Vavg = v->Vrms = v->Vema = v->Irms = v->Prms = 0.0f; // 清零输出
        }
        // 6. 计算信号频率并重置状态
        v->SigFreq = v->SampleFreq * inv_nsamples; // 频率 = 采样率 / 周期采样数
        v->prev_sign = v->curr_sign;               // 更新符号状态
        // 重置所有累加器和计数器
        v->sum_Iacc_rms = v->sum_Pacc_rms = v->sum_Vacc_avg = v->sum_Vacc_rms = v->sum_Vacc_ema = 0.0f;
        v->nsamples = 0; // 重置采样计数器
    }
    else
    {
        // 未检测到ZCD，继续累积当前周期数据
        v->nsamples++; // 采样数递增
        // 累加电压统计量
        v->sum_Vacc_avg += v->curr_vin_norm;                             // 累加电压绝对值（用于Vavg）
        v->sum_Vacc_rms += v->curr_vin_norm * v->curr_vin_norm;          // 累加电压平方（用于Vrms）
        v->sum_Vacc_ema += 0.01f * (v->curr_vin_norm - v->sum_Vacc_ema); // 更新EMA（系数0.01）
        // 累加电流和功率统计量
        v->sum_Iacc_rms += v->curr_iin_norm * v->curr_iin_norm; // 累加电流平方（用于Irms）
        v->sum_Pacc_rms += v->curr_iin_norm * v->curr_vin_norm; // 累加瞬时功率（用于Prms）
        v->ZCD = 0;                                             // 清除ZCD标志
        v->prev_sign = v->curr_sign;                            // 更新前次符号
    }
}
#endif /* SINEANALYZER_DIFF_wPWR_F_H */